home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / irit40s.lha / Irit / poly3d-r / prepdata.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-30  |  6.2 KB  |  186 lines

  1. /*****************************************************************************
  2. *   Routines to    prepare objects for the scan conversion:             *
  3. * At this stage, it is assumed all vertices normals has been evaluated, if   *
  4. * is is required to interpolate them (i.e. Gouraud shading.)             *
  5. * This module sort the polygons into hash table of GlblShadeInfo.ScrnYSize size,         *
  6. * according to their lowest vertex, and update a pointer to it.             *
  7. *                                         *
  8. * Written by:  Gershon Elber                Ver 2.0, Mar. 1990   *
  9. *****************************************************************************/
  10.  
  11. #include <math.h>
  12. #include <stdio.h>
  13. #include <time.h>
  14. #include "program.h"
  15. #include "genmat.h"
  16. #include "iritprsr.h"
  17.  
  18. static void PrepareAllObjects(IPObjectStruct *PObjects);
  19. static void PrepareOnePolygonObject(IPObjectStruct *PObject);
  20. static void PrepareOnePolygon(IPPolygonStruct *PPolygon, int IsPolygon);
  21. static int UpdateBBoxPolygon(IPPolygonStruct *PPolygon);
  22. static void UpdateScanConvertData(int MinVertex, IPPolygonStruct *PPolygon);
  23.  
  24. /*****************************************************************************
  25. * Routine to prepare NumOfObjects given in Objects from FileDescription FD   *
  26. * according to view matrix Mat. If NumOfObjects == 0 then all the objects    *
  27. * defined by the data sturcture are handled, and NumOfObjects is set to real *
  28. * number of objects exists.                             *
  29. *****************************************************************************/
  30. void PrepareViewData(IPObjectStruct *PObjects)
  31. {
  32.     long
  33.     SaveTime = time(NULL);
  34.  
  35.     fprintf(stderr, "\nPass 2, Polys        =      ");
  36.  
  37.     PrepareAllObjects(PObjects);
  38.  
  39.     fprintf(stderr, ",  %ld seconds.", time(NULL) - SaveTime);
  40. #ifdef AMIGA
  41.     fflush(stderr);
  42. #endif /* AMIGA */
  43. }
  44.  
  45. /*****************************************************************************
  46. * Scan all objects.                                 *
  47. *****************************************************************************/
  48. static void PrepareAllObjects(IPObjectStruct *PObjects)
  49. {
  50.     while (PObjects) {
  51.     if (IP_IS_POLY_OBJ(PObjects) && IP_IS_POLYGON_OBJ(PObjects))
  52.         PrepareOnePolygonObject(PObjects);
  53.     PObjects = PObjects -> Pnext;
  54.     }
  55. }
  56.  
  57. /*****************************************************************************
  58. * Routine to prepare one polygon object PObject.                 *
  59. *****************************************************************************/
  60. static void PrepareOnePolygonObject(IPObjectStruct *PObject)
  61. {
  62.     struct IPPolygonStruct
  63.     *PList = PObject -> U.Pl;
  64.  
  65.     while (PList) {
  66.     PrepareOnePolygon(PList, IP_IS_POLYGON_OBJ(PObject));
  67.     PList = PList -> Pnext;
  68.     }
  69. }
  70.  
  71. /*****************************************************************************
  72. * Routine to prepare one polygon PPolygon.                     *
  73. *****************************************************************************/
  74. static void PrepareOnePolygon(IPPolygonStruct *PPolygon, int IsPolygon)
  75. {
  76.     static int
  77.     PolyCount = 0;
  78.     int    i;
  79.     RealType CpCoord[3];
  80.     IPVertexStruct
  81.     *VList = PPolygon -> PVertex;
  82.  
  83.     fprintf(stderr, "\b\b\b\b\b%5d", ++PolyCount);
  84.     GlblNumOfPolys++;
  85.  
  86.     for (; VList != NULL; VList = VList -> Pnext) {
  87.     /* Convert the coordinate to screen space (pres.). */
  88.     MatMultVecby4by4(CpCoord, VList -> Coord, GlblViewMat);
  89.     for (i = 0; i < 3; i++)
  90.         VList -> Coord[i] = CpCoord[i];
  91.     }
  92.  
  93.     if (!IsPolygon)
  94.     return;
  95.  
  96.     /* Find X, Y extremum in screen space, and use the lowest vertex in Y to */
  97.     /* initialize the scan conversion structure of the polygon:             */
  98.     i = UpdateBBoxPolygon(PPolygon);
  99.     UpdateScanConvertData(i, PPolygon);
  100.  
  101.     /* Transform the polygon plane equation as well, and normalize it: */
  102.     UpdateEqnPolygon(PPolygon, FALSE);
  103. }
  104.  
  105. /*****************************************************************************
  106. * Routine to update polygon boundary box in screen space:             *
  107. * Note this routine is called after the    polygons was checked for validity -  *
  108. * all the list of objects was found to be vertices only.             *
  109. *****************************************************************************/
  110. static int UpdateBBoxPolygon(IPPolygonStruct *PPolygon)
  111. {
  112.     int i,
  113.     MinV = 0;
  114.     RealType *Coord, Xmin, Xmax, Ymin, Ymax;
  115.     struct IPVertexStruct
  116.     *VList = PPolygon -> PVertex;
  117.  
  118.     Xmin = Xmax = VList -> Coord[0];
  119.     Ymin = Ymax = VList -> Coord[1];
  120.     for (VList = VList -> Pnext, i = 1;
  121.      VList != NULL;
  122.      VList = VList -> Pnext, i++) {
  123.     Coord = VList -> Coord;
  124.     if (Coord[0] > Xmax)
  125.         Xmax = Coord[0];
  126.     if (Coord[0] < Xmin)
  127.         Xmin = Coord[0];
  128.     if (Coord[1] > Ymax)
  129.         Ymax = Coord[1];
  130.     if (Coord[1] < Ymin) {
  131.         Ymin = Coord[1];
  132.         MinV = i;
  133.     }
  134.     }
  135.  
  136.     PPolygon -> BBox[0][0] = (int) Xmin;
  137.     PPolygon -> BBox[1][0] = (int) Xmax;
  138.     PPolygon -> BBox[0][1] = (int) Ymin;
  139.     PPolygon -> BBox[1][1] = (int) Ymax;
  140.  
  141.     return MinV;
  142. }
  143.  
  144. /*****************************************************************************
  145. * Routine to update polygon scan conversion information:             *
  146. * Each polygon (Remember they must be convex), has two boundaries we cross   *
  147. * by the scan lines if it is active. These are LeftBndry and RightBndry we   *
  148. * update here.                                     *
  149. *****************************************************************************/
  150. static void UpdateScanConvertData(int MinVertex, IPPolygonStruct *PPolygon)
  151. {
  152.     int i;
  153.     struct IPVertexStruct *VMinY, *VBefore, *VAfter,
  154.     *VList = PPolygon -> PVertex;
  155.     struct PolygonScanConvertStruct *PScan;
  156.  
  157.     /* Find the minimum location again: */
  158.     if (MinVertex == 0) {
  159.     /* Its the first vertex that has minimum Y value: */
  160.     VMinY = VList;
  161.     for (VBefore = VList;
  162.          VBefore -> Pnext != NULL;
  163.          VBefore = VBefore -> Pnext);
  164.     VAfter = VList -> Pnext;
  165.     }
  166.  
  167.     else {
  168.     for (i = 1, VBefore = VList;
  169.          i < MinVertex;
  170.          i++, VBefore = VBefore -> Pnext);
  171.     VMinY = VBefore -> Pnext;
  172.     VAfter = VMinY -> Pnext ? VMinY -> Pnext : VList;
  173.     }
  174.  
  175.     PPolygon -> PAux = IritMalloc(sizeof(struct PolygonScanConvertStruct));
  176.     PScan = (PolygonScanConvertStruct *) PPolygon -> PAux;
  177.  
  178.     PScan -> Bndry1.VMinY = VMinY;
  179.     PScan -> Bndry1.VMaxY = VBefore;
  180.     PScan -> Bndry1.MaxEdgeY = (int) VBefore -> Coord[1];
  181.  
  182.     PScan -> Bndry2.VMinY = VMinY;
  183.     PScan -> Bndry2.VMaxY = VAfter;
  184.     PScan -> Bndry2.MaxEdgeY = (int) VAfter -> Coord[1];
  185. }
  186.